本文是总结Tree这种结构的常用知识点,暂时总结Binary Tree。
Binary Tree二叉树
Why Tree?
因为树结合了其他数据结构的优势:
- 顺序数组: 用Binary Search查找会很快。
- 链表:插入和删除会非常快,不需要shift值。
基本概念:
- 根: 树的顶部。
- 父节点
- 子节点
- 叶节点:没有子节点的节点。
- Leve(高度):代表有几代。
平衡树和非平衡树
平衡树: 左右子树及其的高度相差<=1,并且左右子树也是平衡树。
Full Tree 和 Complete Tree:
- Full Tree:每个节点都有0/2个子节点。
- Complete Tree:除了最右边的节点,其他节点都是满节点,并且都靠左。
遍历顺序:
Binary Tree代码实现
Binary Tree Interface
Binary Tree功能实现
-
Find:
123456789101112131415161718192021222324public boolean find(int key) {// tree is emptyif (root == null) {return false;}Node curr = root;// while not foundwhile (curr.key != key) {if (curr.key < key) {// go rightcurr = curr.right;} else {// go leftcurr = curr.left;}// not foundif (curr == null) {return false;}}return true; // found} -
Insert
12345678910111213141516171819202122232425262728293031323334353637public void insert(int key, double value) {Node newNode = new Node(key, value);// empty treeif (root == null) {root = newNode;return;}Node parent = root; // keep track of parentNode curr = root;while (true) {// no duplicate keys allowed// simply keep the existing one hereif (curr.key == key) {return;}parent = curr; // update parentif (curr.key < key) {// go rightcurr = curr.right;if (curr == null) {// found a spotparent.right = newNode;return;}} else {// go leftcurr = curr.left;if (curr == null) {// found a spotparent.left = newNode;return;}} // end of if-else to go right or left} // end of while} // end of insert method -
Delete
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374public void delete(int key) {// empty treeif (root == null) {return;}Node parent = root;Node curr = root;/** flag to check left child** need this flag because actual deletion process happens after the* while loop that is to find the key to delete*/boolean isLeftChild = true;while (curr.key != key) {parent = curr; // update parent firstif (curr.key < key) { // go rightisLeftChild = false;curr = curr.right;} else { // go leftisLeftChild = true;curr = curr.left;}// case 1: not foundif (curr == null) {return;}}if (curr.left == null && curr.right == null) {// case 2: leafif (curr == root) {root = null;} else if (isLeftChild) {parent.left = null;} else {parent.right = null;}} else if (curr.right == null) {// case 3: no right childif (curr == root) {root = curr.left;} else if (isLeftChild) {parent.left = curr.left;} else {parent.right = curr.left;}} else if (curr.left == null) {// case 3: no left childif (curr == root) {root = curr.right;} else if (isLeftChild) {parent.left = curr.right;} else {parent.right = curr.right;}} else {// case 4: with two children// here we use successor but using predecessor is also an optionNode successor = getSuccessor(curr);if(curr == root) {root = successor;} else if(isLeftChild) {parent.left = successor;} else {parent.right = successor;}successor.left = curr.left;}} -
找到下一个节点
1234567891011121314151617181920212223242526272829303132/*** Helper method to find the successor of the toDelete node.* This tries to find the smallest value of the right subtree* of the toDelete node by going down to the left most node in the subtree* @param toDelete node to delete* @return the successor of the toDelete node*/private Node getSuccessor(Node toDelete) {Node successorParent = toDelete;Node successor = toDelete;// start the search from the root of the right subtreeNode curr = toDelete.right;// move down to left as far as possible in the right subtree// successor's left child must be nullwhile (curr != null) {successorParent = successor;successor = curr;curr = curr.left;}/** If successor is NOT the right child of the node to delete, then* need to take care of two connections in the right subtree*/if (successor != toDelete.right) {successorParent.left = successor.right;successor.right = toDelete.right;}return successor;} -
Traverse Binary Tree:
123456789101112public void traverse() {inOrderHelper(root);System.out.println();}private void inOrderHelper(Node toVisit) {if(toVisit != null) {inOrderHelper(toVisit.left);System.out.print(toVisit);inOrderHelper(toVisit.right);}}
Reference: @Terry Lee